#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @FileName  :run.py
# @Time      :2021/03/25 14:21:41
# @Author    :Raink


import time
import uvicorn
from fastapi import FastAPI, Request
from fastapi.staticfiles import StaticFiles
from tutorial import app03, app04, app05, app06, app07, app08
from coronavirus import applications

# chapter04:改写默认错误处理程序
from fastapi.exceptions import RequestValidationError
from fastapi.responses import PlainTextResponse  # 用文本的形式返回response
# 下面两个包实际上是一样的，fastapi中HTTPException是对starlette中的HTTPException的封装
# from fastapi.exceptions import HTTPException
from starlette.exceptions import HTTPException as StarletteHTTPException

app = FastAPI(
    title="FastAPI Tutorial and Coronavirus Tracker API Docs",
    description='FastAPI教程 新冠病毒疫情跟踪API接口文档',
    version="1.0.0",
    docs_url="/docs",
    redoc_url="/redocs"
)

"""
静态文件的配置
1、创建static文件夹
2、from fastapi.staticfiles import StaticFiles
3、把静态文件目录挂载到app中
注意不能挂载到APIRouter()实例中，只能挂载到FastAPI()实例中
"""
app.mount(path="/coronavirus/static", app=StaticFiles(directory="./coronavirus/static"))

# chapter04:改写默认错误处理程序
@app.exception_handler(StarletteHTTPException)
async def http_exception_handler(request, exc):
    """request参数不可省略"""
    return PlainTextResponse(str(exc.detail), status_code=exc.status_code)

@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc):
    return PlainTextResponse(str(exc), status_code=400)


# 中间件
@app.middleware('http')
async def add_process_time_header(request: Request, call_next):
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response

# 跨域资源共享
from fastapi.middleware.cors import CORSMiddleware

app.add_middleware(
    CORSMiddleware,
    # 信任的列表
    allow_origins = [
        "http://127.0.0.1",
        "http://127.0.0.1:8080"
    ],
    allow_credentials=True,  # 允许使用证书
    allow_methods=["*"],  # 允许跨域的方法  *允许所有的
    allow_headers=["*"],  # 允许的请求头
)


app.include_router(app03, prefix="/chapter03", tags=["第三章 请求参数和验证"])
app.include_router(app04, prefix="/chapter04", tags=["第四章 响应处理和Fastapi配置"])
app.include_router(app05, prefix="/chapter05", tags=["第五章 FastAPI的依赖注入系统"])
app.include_router(app06, prefix="/chapter06", tags=["第六章 OAuth2.0的授权模式"])
app.include_router(app07, prefix="/chapter07", tags=["第七章 数据库操作和多应用的目录结构设计"])
app.include_router(app08, prefix="/chapter08", tags=["第八章 中间件、CORS、后台任务、测试用例"])
app.include_router(applications, prefix="/coronavirus", tags=["实战项目：新冠疫情API"])


if __name__ == "__main__":
    uvicorn.run('run:app', host='192.168.1.52', port=4539, reload=True, debug=True, workers=1)